package readini

import (
	"bufio"
	"fmt"
	"os"
)

// Configuration 存储该配置文件内所有分区 section.
type Configuration struct {
	// 存储分区名 section name.
	SectionList []string
	// section name 和 section 之间的映射.
	Sections map[string]*Section
}

func (cfg *Configuration) init() {
	cfg.Sections = make(map[string]*Section)
}

// newSection 创建新分区 section.
func (cfg *Configuration) newSection(secName string) error {
	if len(secName) == 0 {
		return fmt.Errorf("Empty section name")
	}
	if cfg.Sections[secName] != nil {
		return fmt.Errorf("Section[%v] already exists", secName)
	}

	cfg.SectionList = append(cfg.SectionList, secName)
	cfg.Sections[secName] = &Section{
		KeyVal: make(map[string]string),
	}

	return nil
}

// GetSection returns 根据分区名 section name 返回对应的分区 section.
func (cfg *Configuration) GetSection(secName string) (*Section, error) {
	if len(secName) == 0 {
		secName = DefaultSection
	}
	sec := cfg.Sections[secName]
	if sec == nil {
		return nil, fmt.Errorf("Section[%v] does not exist", secName)
	}
	return sec, nil
}

// GetSectionList returns 返回该配置文件中所有分区名 section name 组成的列表.
func (cfg *Configuration) GetSectionList() []string {
	sectionList := make([]string, len(cfg.SectionList))
	for i := range cfg.SectionList {
		sectionList[i] = cfg.SectionList[i]
	}
	return sectionList
}

// Load 读取 ini 配置文件.
func Load(filename string) (*Configuration, error) {
	file, err := os.Open(filename)
	if err != nil {
		return nil, err
	}
	defer file.Close()

	buffer := bufio.NewReader(file)
	var cfg Configuration
	cfg.init()
	err = parse(&cfg, buffer)

	if err != nil {
		return nil, err
	}

	return &cfg, nil
}
